package com.t.codebook.filter;
import com.t.codebook.common.ErrorCode;
import com.t.codebook.constant.CommonConstant;
import com.t.codebook.exception.BusinessException;
import com.t.codebook.exception.ThrowUtils;
import com.t.codebook.utils.JWTUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.UUID;

/**
* @Description: JWT 过滤器
* @Param:
* @return:
* @Author: tangzhaofeng
* @Date: 8/26/2024
*/
@Component
@Slf4j
public class JWTFilter extends OncePerRequestFilter {

    @Resource
    private JWTUtils jwtUtils;

    private String[] doFilterUrl = {"/api/user/login","/api/doc.html","/api/webjars/**","/api/swagger-resources","/api/v2/**"};

    /**
    * @Description: 判断是否是可放行URL
    * @Param:
    * @return:
    * @Author: tangzhaofeng
    * @Date: 8/26/2024
    */
    private boolean isDoFilterUrl(String url) {
        for (String filterUrl : doFilterUrl) {
            if (filterUrl.contains("**")){
                //如果过滤Url包含了**通配符
                if (url.contains(filterUrl.replace("**",""))){
                    return true;
                }
            }
            if (url.equals(filterUrl)) {
                return true;
            }
        }
        return false;
    }


    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String requestURI = request.getRequestURI();
        if (isDoFilterUrl(requestURI)) {
            //判断是否是可放行请求
            doFilter(request, response, filterChain);
        }else{
            // 生成请求唯一 id
            String requestId = UUID.randomUUID().toString();
            // 输出请求日志
            log.info("request start，id: {}, path: {}, ip: {}", requestId, requestURI, request.getRemoteHost());
            //从request中获取Authorization
            String authorization = request.getHeader("Authorization");
            //校验Authorization是否具备正确格式
            ThrowUtils.throwIf(authorization == null , ErrorCode.TOKEN_ISNULL);
            ThrowUtils.throwIf(!authorization.startsWith(CommonConstant.TOKEN_PREFIX),ErrorCode.TOKEN_ERROR);
            //去除Token 前缀
            String token = authorization.replace(CommonConstant.TOKEN_PREFIX, "");
            //校验Token
            try{
                jwtUtils.verifyToken(token);
            }catch (Exception e){
                throw new BusinessException(ErrorCode.TOKEN_ERROR);
            }
            //校验成功,续期Token
            jwtUtils.renewalToken(token);
            filterChain.doFilter(request,response);
        }
    }


}
